package com.swim.session;

import java.util.List;

import javax.ejb.Stateless;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.persistence.EntityManager;
import javax.persistence.EntityNotFoundException;
import javax.persistence.NonUniqueResultException;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.jboss.ejb3.annotation.LocalBinding;
import org.jboss.ejb3.annotation.RemoteBinding;

import com.swim.entity.Collaboration;

@Stateless
@RemoteBinding(jndiBinding="CollaborationBeanJNDI")
@LocalBinding(jndiBinding="CollaborationBeanLocalJNDI")
public class CollaborationBean implements CollaborationRemote, CollaborationLocal{
	
	@PersistenceContext(unitName = "SWIM")
	EntityManager database;
	
	
	/**
	 * @param offering the user who offers a collaboration
	 * @param receiving the user who receives a collaboration
	 * @param shillName ehe name of the skill used for the collaboration
	 */
	public void newCollaboration(String offering, String receiving, String skillName) {
		RegisteredUserLocal r = getRegisteredUserLocal();
		SkillLocal s = getSkillLocal();
		Collaboration c = new Collaboration(Util.getNow(), r.getUserWithEmail(offering), 
				r.getUserWithEmail(receiving), s.getSkillByName(skillName), null);
		database.persist(c);
	}
	
	/**
	 * @param id the id of the collaboration
	 * @return the collaboration selected by the id
	 */
	public Collaboration getCollaboration(int id) {
		try{
			Query q = database.createQuery("SELECT c FROM Collaboration c WHERE c.id=:id");
			q.setParameter("id", id);
			Collaboration result =  (Collaboration) q.getSingleResult();
			return result;
	   	} catch (EntityNotFoundException exc) { 
			System.err.println("UFF1");
		} catch (javax.persistence.NoResultException exc) { 
			System.err.println("UFF2");
		} catch (NonUniqueResultException exc) {
			System.err.println("UFF3");
		}
		return null;
	}

	/**
	 * @param emailTo the email of the person who gived a collaboration
	 * @return the list of the collaboration gived by an user
	 */
	public List<Collaboration> getReceivedCollaborations(String emailTo) {
		try{
			Query q = database.createQuery("SELECT c FROM RegisteredUser as r, IN (r.receivedCollaborations) c WHERE r.email=:email");
			q.setParameter("email", emailTo);
			List<Collaboration> result =  (List<Collaboration>) q.getResultList();
			return result;
	   	} catch (EntityNotFoundException exc) { 
			System.err.println("UFF1");
		} catch (javax.persistence.NoResultException exc) { 
			System.err.println("UFF2");
		} catch (NonUniqueResultException exc) {
			System.err.println("UFF3");
		}
		return null;
	}
	
	/**
	 * @param emailFrom the email of the person who received a collaboration
	 * @return the list of the collaboration received by an user
	 */
	public List<Collaboration> getOfferedCollaborations(String emailFrom) {
		try{
			Query q = database.createQuery("SELECT c FROM RegisteredUser as r, IN (r.offeredCollaborations) c WHERE r.email=:email");
			q.setParameter("email", emailFrom);
			List<Collaboration> result =  q.getResultList();
			return result;
	   	} catch (EntityNotFoundException exc) { 
			System.err.println("UFF1");
		} catch (javax.persistence.NoResultException exc) { 
			System.err.println("UFF2");
		} catch (NonUniqueResultException exc) {
			System.err.println("UFF3");
		}
		return null;
	}
	
	/**
	 * @return the local interface of registered user
	 */
	private RegisteredUserLocal getRegisteredUserLocal() {
		InitialContext jndiContext;
		Object ref = null;
		try {
			jndiContext = new InitialContext();
			ref = jndiContext.lookup("RegisteredUserBeanLocalJNDI");
		} catch (NamingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return (RegisteredUserLocal) ref;
	}
	
	/**
	 * @return the local interface of skill
	 */
	private SkillLocal getSkillLocal() {
		InitialContext jndiContext;
		Object ref = null;
		try {
			jndiContext = new InitialContext();
			ref = jndiContext.lookup("SkillBeanLocalJNDI");
		} catch (NamingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return (SkillLocal) ref;
	}
}
